<% properties_with_classes(object.all_user_properties).each do |prop| -%>
class <%= prop.property_class[-1] -%>(object):
<% if prop.is_a?(Api::Type::NestedObject) -%>
    def __init__(self, request):
        if request:
            self.request = request
        else:
            self.request = {}

    def to_request(self):
        return {
<%= lines(request_properties_in_classes(prop.properties, 12)) -%>
        }

    def from_response(self):
        return {
<%= lines(response_properties_in_classes(prop.properties, 12)) -%>
        }
<%   properties_with_custom_method_for_param(prop.properties).each do |p| -%>
<%     if p.to_request -%>

<%       if p.to_request.include?('self') -%>
    def _<%= p.out_name -%>_convert_to_request(self, value):
<%       else -%>
    @staticmethod
    def _<%= p.out_name -%>_convert_to_request(value):
<%       end -%>
<%= lines(indent(convert_custom_method(p, p.to_request), 8)) -%>
<%     end -%>
<%     if p.from_response -%>

<%       if p.from_response.include?('self') -%>
    def _<%= p.out_name -%>_convert_from_response(self, value):
<%       else -%>
    @staticmethod
    def _<%= p.out_name -%>_convert_from_response(value):
<%       end -%>
<%= lines(indent(convert_custom_method(p, p.from_response), 8)) -%>
<%     end -%>
<%   end -%>
<% elsif prop.is_a?(Api::Type::Array) && prop.item_type.is_a?(Api::Type::NestedObject) -%>
    def __init__(self, request):
        if request:
            self.request = request
        else:
            self.request = []

    def to_request(self):
        items = []
        for item in self.request:
            items.append(self._request_for_item(item))
        return items

    def from_response(self):
        items = []
        for item in self.request:
            items.append(self._response_from_item(item))
        return items

    def _request_for_item(self, item):
        return {
<%=
  lines(request_properties_in_classes(prop.item_type.properties, 12, 'item'))
-%>
        }

    def _response_from_item(self, item):
        return {
<%=
  lines(response_properties_in_classes(prop.item_type.properties, 12, 'item'))
-%>
        }
<%   properties_with_custom_method_for_param(prop.item_type.properties).each do |p| -%>
<%     if p.to_request -%>

<%       if p.to_request.include?('self') -%>
    def _<%= p.out_name -%>_convert_to_request(self, value):
<%       else -%>
    @staticmethod
    def _<%= p.out_name -%>_convert_to_request(value):
<%       end -%>
<%= lines(indent(convert_custom_method(p, p.to_request), 8)) -%>
<%     end -%>
<%     if p.from_response -%>

<%       if p.from_response.include?('self') -%>
    def _<%= p.out_name -%>_convert_from_response(self, value):
<%       else -%>
    @staticmethod
    def _<%= p.out_name -%>_convert_from_response(value):
<%       end -%>
<%= lines(indent(convert_custom_method(p, p.from_response), 8)) -%>
<%     end -%>
<%   end -%>
<% end # prop.is_a? NestedObject -%>
<%=
  unless prop == properties_with_classes(object.all_user_properties).last
    "\n" * 2
  end
-%>
<% end -%>
<% properties_with_custom_method_for_param(object.all_user_properties).each do |prop| -%>
<%   if prop.to_request -%>
<%= "\n" * 2 -%>
def _<%= prop.out_name -%>_convert_to_request(value):
<%= lines(indent(convert_custom_method(prop, prop.to_request), 4)) -%>
<%   end -%>
<%   if prop.from_response -%>
<%= "\n" * 2 -%>
def _<%= prop.out_name -%>_convert_from_response(value):
<%= lines(indent(convert_custom_method(prop, prop.from_response), 4)) -%>
<%   end -%>
<% end -%>
<% unless object.ex_properties.empty? -%>
<%= "\n" * 2 -%>
<%   object.ex_properties.each do |prop|
       opts = prop.ex_property_opts
       get_url = opts&.get_url&.gsub('{{', '{')&.gsub('}}', '}')
       update_url = prop.update_url.gsub('{{', '{').gsub('}}', '}')
       prop_service_type = opts&.service_type || prop.__resource.service_type
-%>
class <%= prop.property_class[-1] -%>ExProperty(object):
    def __init__(self, session):
        self.module = session.module
        self.session = session

<%     if get_url && get_url == update_url -%>
<%= lines(indent(emit_link('_link', get_url, object, false, prop_service_type, true), 4)) -%>

<%     else -%>
<%       if get_url -%>
<%= lines(indent(emit_link('_link_get', get_url, object, false, prop_service_type, true), 4)) -%>

<%       end -%>
<%= lines(indent(emit_link('_link_update', update_url, object, false, prop_service_type, true), 4)) -%>

<%     end -%>
<%     if get_url -%>
    def fetch(self):
<%=
  indent(send_request(
    "return self.session.get(" + (get_url == update_url ? 'self._link()' : 'self._link_get()') + ")",
  ), 8)
%>
<%     end # end get_url -%>

    def update(self):
        request = remove_nones_from_dict({
<%= lines(indent(request_properties([prop], 4, true), 8)) -%>
        })
<%
  if prop.update_verb.nil? || prop.update_verb == :POST
    update_verb = 'post'
  elsif prop.update_verb == :PUT
    update_verb = 'put'
  else
    raise "Ansible does not support update_verb #{prop.update_verb}"
  end
-%>
<%=
  indent(send_request(
    "self.session.#{update_verb}(" + (get_url == update_url ? 'self._link()' : 'self._link_update()') + ', request)',
  ), 8)
%>
<%       if get_url -%>
        return self.fetch()
<%       else -%>
        return None
<%       end -%>
<%=
       unless prop == object.ex_properties.last
    "\n" * 2
       end
-%>
<%   end -%>
<% end -%>
